#ifndef __BUOLA_GUI_X11_CX11SYNC_H__
#define __BUOLA_GUI_X11_CX11SYNC_H__

#include <buola/utility/usignal.h>
#include <buola/gui/x11/auto.h>

#include <X11/Xlib.h>
#include <X11/extensions/sync.h>

namespace buola { namespace gui { namespace x11 {

class CX11SyncCounter
{
public:
    enum EWaitType
    {
        SYNC_NONE=0,
        SYNC_TRANSITION=(1<<0),
        SYNC_NEGATIVE=(1<<1),
        SYNC_RELATIVE=(1<<2),
        SYNC_DELETE=(1<<3)
    };
    DECLARE_FRIEND_ENUM_BITOPS(EWaitType)

    CX11SyncCounter(int64_t);
    CX11SyncCounter(TID,bool pOwn);
    CX11SyncCounter(const std::wstring&);
    ~CX11SyncCounter();

    void Set(int64_t);
    void Add(int64_t);
    int64_t Get();

    void Await(int64_t pValue,EWaitType pFlags=SYNC_NONE,int pTimeout=-1);

    TID GetID() const           {   return mID;     }

    static const std::vector<std::wstring> &GetSystemCounterList();

private:
    TID mID;
    bool mOwned;

public:
    static bool mInitStatic;
    static int mEvent;
    static void *mSystemCounters;
    static std::vector<std::wstring> mSystemCounterList;
};

class CX11SyncAlarm : public UUncopiable
{
public:
    CX11SyncAlarm(const CX11SyncCounter&,int64_t,
                  CX11SyncCounter::EWaitType=CX11SyncCounter::SYNC_NONE,int64_t pDelta=0);
    ~CX11SyncAlarm();

    void Trigger();

    TID GetID() const           {   return mID;     }

    static const std::vector<CX11SyncAlarm*> &GetAll()
                                {   return mAll;    }
public:
    USignal<void()> sTriggered;

private:
    CX11SyncCounter mCounter;
    TID mID;
    bool mDelete;

    static std::vector<CX11SyncAlarm*> mAll;
};

/*namespace x11*/ } /*namespace gui*/ } /*namespace buola*/ }

#endif
